home *** CD-ROM | disk | FTP | other *** search
- #include <fstream.h>
- #include <stdio.h>
- #include <conio.h>
- #include <string.h>
- #include <mem.h>
- #include <dos.h>
- #include <alloc.h>
- #include <io.h>
- #include <stdlib.h>
- #include "xlib.h"
- #include "xrect.h"
- #include "xpbitmap.h"
- #include "xcbitmap.h"
- #include "xpal.h"
- #include "icon.h"
-
- int widthFour(int width)
- {
- return (width + (((4-(width % 4)) == 4) ? 0 : (4-(width%4)))); //smallest mult of 4 > width!
- }
-
- char * unRollBlt(char * rolledBlt, int & iwidth, int & iheight)
- {
- char * temp = NULL;
- int * width = (int *)&rolledBlt[0];
- iwidth = *width;
- int * height = (int *)&rolledBlt[2];
- iheight = *height;
- char * tempimage = &rolledBlt[4];
- int row, col, i, j, k, width4;
- int heightCounter, widthCounter;
- width4 = widthFour(*width);
- int newHeight = *height;
- temp = new char[width4*newHeight + 4];
- if (temp == NULL) {delete temp; return NULL;}
- temp[0] = (width4)/4;
- temp[1] = *height;
- k = 2;
- for (i=0; i<4; i++)
- for (heightCounter = 0; heightCounter < *height; heightCounter +=1)
- for (widthCounter=0; widthCounter < width4; widthCounter += 4, k++)
- {
- if (((widthCounter + i) >= *width))
- temp[k] = 0;
- else
- temp[k] = tempimage[i + (heightCounter* *width) + widthCounter];
- }
- return (char far *)temp;
- }
-
- char * rollBlt(char * unRolledBlt, int & iwidth, int &iheight)
- {
- int width4 = 4*unRolledBlt[0];
- int height = unRolledBlt[1];
- char *returnBuffer = new char [iwidth * iheight + 4];
- if (returnBuffer == NULL)
- return NULL;
- *(int *)&returnBuffer[0] = iwidth;
- *(int *)&returnBuffer[2] = iheight;
- int k = 2;
- for (int i = 0; i < 4; ++i) //each of the four loops!
- for(int heightCounter = 0; heightCounter < height; ++heightCounter)
- for(int widthCounter = 0; widthCounter < width4; widthCounter += 4)
- {
- if (widthCounter + i < iwidth)
- returnBuffer[i + heightCounter*iwidth + widthCounter + 4] = unRolledBlt[k];
- k++;
- }
- return(returnBuffer);
- }
-
- char far *
- AllocatedSprite(int logicalWidth, char * bitmap)
- {
- char * result;
- int size;
-
- result = new char[(bitmap[0] * bitmap[1] * 7) / 2 + 25];
- if (result == 0)
- return(0);
- size = x_compile_bitmap(logicalWidth, bitmap, result);
-
- return (char far *)farrealloc(result, size);
- }
-
-
- byte icon::getPixel(int x, int y)
- {
- int width4 = 4*unrolledPic[0];
- return unrolledPic[((x % 4)*(width4*height/4) + x/4 + y*width4/4) +2 ];
- }
-
- void icon::hide(int x, int y, word toOffset, word fromOffset)
- {
- x_cp_vid_rect(x, y, x+(width), y+height, x, y,
- fromOffset, toOffset,
- ScrnLogicalPixelWidth,ScrnLogicalPixelWidth);
- }
-
- void icon::show(int x, int y, word offset)
- {
- if (unrolledPic != NULL)
- {
- if (flags == normal)
- x_put_pbm(x, y, offset, unrolledPic);
- else if (flags == fast)
- x_put_cbitmap(x, y, offset, unrolledPic);
- }
- }
-
- void icon::showMasked(int x, int y, word offset)
- {
- if (unrolledPic != NULL)
- {
- if (flags == normal)
- x_put_masked_pbm(x, y, offset, unrolledPic);
- else if (flags == fast)
- x_put_cbitmap(x, y, offset, unrolledPic);
- }
- }
-
- void icon::save(char * filename)
- {
- long miscNumber = 0;
- long bufferIndex = 0;
- if (flags != fast)
- {
- ofstream myOutStream(filename, ios::out | ios::binary);
- if (myOutStream)
- {
- myOutStream.write("YARFILE ", 10);
- myOutStream.write((char *) &width, sizeof(width));
- myOutStream.write((char *) &height, sizeof(height));
- int width4 = widthFour(width);
- for (long bytesLeft = (long)width4 * (long)height + 2; bytesLeft > 0;)//
- {
- miscNumber = (bytesLeft < 32000) ? bytesLeft : 32000;
- myOutStream.write(unrolledPic + bufferIndex, (int)miscNumber);
- bytesLeft -= miscNumber;
- bufferIndex += miscNumber;
- }
- myOutStream.close();
- }
- }
- }
-
- char *icon::useData(unsigned char * myPointer, flagType iflags)
- //for use with bin2hdr files!!
- {
- if (unrolledPic)
- delete unrolledPic;
- flags = iflags;
- width = *(int *) &myPointer[10];
- height = *(int *) &myPointer[12];
- if (flags == normal)
- {
- int width4 = widthFour(width);
- unrolledPic = new char[width4 * height + 2];//
- memcpy(unrolledPic, &myPointer[14], (width4 * height + 2));//
- makeCollisionMap();
- return(unrolledPic);
- }
- else if (flags == fast)
- {
- char * tempRolled = rollBlt(myPointer + 14, width, height);
- tempRolled[2] = (char) width;
- tempRolled[3] = (char) height;
- unrolledPic = AllocatedSprite(ScrnLogicalPixelWidth/4, tempRolled + 2);
- delete tempRolled;
- makeCollisionMap();
- return(unrolledPic);
- }
- else return(NULL);
- }
-
- char * icon::load(char * filename, flagType iflags, yakLib * myYakLib)
- {
- char * tempBuffer = NULL;
- if (myYakLib)
- tempBuffer = myYakLib->loadToMem(filename);
- else
- tempBuffer = loadDosToMem(filename);
- if ((tempBuffer == NULL) || (strncmp(tempBuffer, "YARFILE", 7)))
- {
- unrolledPic = NULL;
- return(NULL);
- }
- else
- {
- char* tempReturnValue = useData(tempBuffer, iflags);
- delete tempBuffer;
- return tempReturnValue;
- }
- }
-
- //collision code goes in here.
-
- //the cbox map array is in [y][x] format, in order to use the more elegant
- //and very fast bitwise operators. This is contrary to the familiar icon
- //bitmap [x][y] structure.
-
- int icon::setWPacked(int xwid, int y1)
- {
- int x8 = (xwid >> 3) + ((xwid & 7) > 0);
- if (collisionMap) delete collisionMap;
- collisionMap = new byte[x8 * y1];
- if (collisionMap == NULL)
- return 0;
- else
- byteWidth = x8;
- return 1;
- }
-
- int icon::setCollisionBit(int ix, int iy, booleanFlags flag)
- {
- byte bitPixel = 128; // ie 1000 0000
- bitPixel >>= ix % 8; // right shift it...
- if (flag == on)
- collisionMap[iy * byteWidth + (int)(ix/8)] |= bitPixel;
- else if (flag == off)
- collisionMap[iy * byteWidth + (int)(ix/8)] &= ~bitPixel;
- return bitPixel;
- }
-
- int icon::getCollisionBit(int ix, int iy)
- {
- byte bitPixel = 128;
- bitPixel >>= ix%8;
- return (collisionMap[iy * byteWidth + (int)(ix/8)] & bitPixel) ? 1 : 0;
- }
-
- void icon::spewCollisionTable(void)
- {
- for (int heightCounter = 0; heightCounter < height; ++heightCounter)
- {
- for (int widthCounter = 0; widthCounter < byteWidth*8; ++widthCounter)
- cout << getCollisionBit(widthCounter, heightCounter);
- cout << '\n';
- }
- }
-
-
- int icon::makeCollisionMap()
- {
- setWPacked(width, height);
- for (int heightCounter = 0; heightCounter < height; ++heightCounter)
- for (int widthCounter = 0; widthCounter < byteWidth*8; ++widthCounter)
- setCollisionBit(widthCounter, heightCounter, (getPixel(widthCounter, heightCounter) == 0) ? off : on);
- return 1;
- }
-
- int icon::hitXY(int myX, int myY, icon* target, int targetX, int targetY)
- {
- int overlapTop = (myY > targetY) ? myY : targetY;
- int overlapBottom = (myY+height > targetY + target->height) ?
- (targetY + target->height) :
- (myY + height);
- if (overlapTop > overlapBottom) return 0;
- int overlapLeft = (myX > targetX) ? myX : targetX;
- int overlapRight = (myX + width > targetX + target->width) ?
- (targetX + target->width) :
- (myX + width);
- int overlapWidth = overlapRight - overlapLeft;
- if (overlapWidth < 0) return 0;
- int overlapByteWidth = (overlapWidth >> 3) + ((overlapWidth & 7) > 0);
- //now we know what the tops and bottoms of the overlap are. Now our
- //task is to find the offsets in each collisionMap to start checking.
- byte * myOffset = collisionMap, * targetOffset = target->collisionMap;
- myOffset += (myY > targetY) ? 0 : byteWidth*(overlapTop - myY); //y part
- myOffset += (myX > targetX) ? 0 : (overlapLeft - myX) >> 3;
- targetOffset += (targetY > myY) ? 0 : target->byteWidth*(overlapTop - targetY);
- targetOffset += (targetX > myX) ? 0 : (overlapLeft - targetY) >> 3;
- int myStep = byteWidth - overlapByteWidth;
- int targetStep = target->byteWidth - overlapByteWidth;
-
- int shift = (7 - (overlapWidth & 7));
-
- for (int heightCounter = overlapTop; heightCounter <= overlapBottom; ++heightCounter)
- {
- for (int widthCounter = 0; widthCounter < overlapByteWidth; ++ widthCounter)
- {
- if ((myX < targetX) ?
- (*myOffset & (*targetOffset >> shift)) :
- (*myOffset & (*targetOffset << shift))) return 1;
- ++myOffset;
- ++targetOffset;
- }
- myOffset += myStep;
- targetOffset += targetStep;
- }
-
- return 0;
- }
-
-
-
- //icon zooming code goes here----------------------------------------->
-
- byte ** icon::zoomTable = NULL;
- int icon::zoomTableWidth = 0;
-
- byte ** icon::setZoomTable(int newWidth)
- {
- float interval = 0;
- float tempNumber = 0, secondTempNumber = 0;
- if (zoomTable)
- delete zoomTable;
- zoomTable = new byte*[newWidth];
- if (!zoomTable) return NULL;
- for (int counter = 0; counter < newWidth; ++counter)
- zoomTable[counter] = new byte[newWidth];
- if (!zoomTable[newWidth - 1]) return NULL;
- zoomTableWidth = newWidth;
- for (int heightCounter = 0; heightCounter < newWidth; ++heightCounter)
- {
- interval = (((float)newWidth) / ((float)heightCounter+1)); //+1 for div by 0
- tempNumber = secondTempNumber = 0;
- for (int widthCounter = 0; widthCounter < newWidth; ++widthCounter)
- {
- secondTempNumber = ((float)widthCounter + 1) / interval;
- if ((secondTempNumber - tempNumber) >= 1)
- {
- zoomTable[heightCounter][widthCounter] = 1;
- tempNumber += 1;
- }
- else
- zoomTable[heightCounter][widthCounter] = 0;
- }
- }
- return zoomTable;
- }
-
- void icon::spewZoomTable(void)
- {
- for (int heightCounter = 0; heightCounter < zoomTableWidth; ++heightCounter)
- {
- for (int widthCounter = 0; widthCounter < zoomTableWidth; ++widthCounter)
- cout << (int)zoomTable[heightCounter][widthCounter];
- cout << '\n';
- }
- }
-
- icon * icon::zoomedIcon(int newWidth)
- {
- int numberOfDots = newWidth / zoomTableWidth; //number of times each dot is drawn
- int tempPosition = newWidth % zoomTableWidth - 1; //position in zoom table
- if (tempPosition < 0)
- {
- numberOfDots--;
- tempPosition = zoomTableWidth - 1;
- }
- byte * zoomReference = zoomTable[tempPosition];
- int width4 = widthFour(newWidth);
- byte * zoomedIcon = new byte[width4 * newWidth + 2];
- if (!zoomedIcon)
- return NULL;
- *(byte *)&zoomedIcon[0] = (byte)(widthFour(newWidth)/4);
- *(byte *)&zoomedIcon[1] = (byte)(newWidth);
- byte * currentZoomedPointer = zoomedIcon+2; //current position in new buffer
- byte * currentUnzoomedPointer = unrolledPic+2;
- int zoomedFourCounter = 0; //what step of the four strings we're on
- int unzoomedFourCounter = 0;
- int zoomedInterval = (zoomedIcon[0]*zoomedIcon[1]); //how much to increment
- int zoomedInterval4 = 4*zoomedInterval;
- int unzoomedInterval = (unrolledPic[0]*unrolledPic[1]); //our pointers
- int unzoomedInterval4 = 4*unzoomedInterval;
- byte * tempLinePointer = NULL; //we need this to duplicate lines
- int heightCounter, widthCounter, lineCounter, dotCounter;
- int dotsDone = 0;
- int linesDone = 0;
- for (heightCounter = 0; heightCounter < zoomTableWidth; ++heightCounter)
- {
- for (lineCounter = 0,tempLinePointer = currentUnzoomedPointer; lineCounter < (numberOfDots + zoomReference[heightCounter]); ++lineCounter)
- {
- ++linesDone;
- currentUnzoomedPointer = tempLinePointer;
- dotsDone = 0;
- for (widthCounter = 0; widthCounter < zoomTableWidth; ++widthCounter)
- {
- for (dotCounter = 0; dotCounter < (numberOfDots + zoomReference[widthCounter]); ++dotCounter)
- {
- *currentZoomedPointer = *currentUnzoomedPointer;
- zoomedFourCounter++;
- currentZoomedPointer += zoomedInterval;
- if (zoomedFourCounter == 4)
- {
- zoomedFourCounter = 0;
- currentZoomedPointer -= (zoomedInterval4 - 1);
- }
- ++dotsDone;
- }
- unzoomedFourCounter++;
- currentUnzoomedPointer += unzoomedInterval;
- if (unzoomedFourCounter == 4)
- {
- unzoomedFourCounter = 0;
- currentUnzoomedPointer -= (unzoomedInterval4 - 1);
- }
- }
- for (;dotsDone < width4; ++dotsDone)
- {
- *currentZoomedPointer = 0;
- zoomedFourCounter++;
- currentZoomedPointer += zoomedInterval;
- if (zoomedFourCounter == 4)
- {
- zoomedFourCounter = 0;
- currentZoomedPointer -= (zoomedInterval4 - 1);
- }
- }
- }
- currentUnzoomedPointer = tempLinePointer + unrolledPic[0];
- }
- for (;linesDone < newWidth; ++linesDone)
- {
- for (dotsDone = 0; dotsDone < width4; ++dotsDone)
- {
- *currentZoomedPointer = 0;
- zoomedFourCounter++;
- currentZoomedPointer += zoomedInterval;
- if (zoomedFourCounter == 4)
- {
- zoomedFourCounter = 0;
- currentZoomedPointer -= (zoomedInterval4 - 1);
- }
- }
- }
- icon * returnIcon = new icon;
- returnIcon->unrolledPic = zoomedIcon;
- returnIcon->flags = icon::normal;
- returnIcon->width = returnIcon->height = newWidth;
- returnIcon->collisionMap = NULL;
- return returnIcon;
- }
-
- void icon::showZoomed(int x, int y, word offset, int newWidth)
- {
- icon * tempIcon = zoomedIcon(newWidth);
- tempIcon->showMasked(x, y, offset);
- delete tempIcon;
- }